package com.labtalk.admin.service.impl;

import com.alibaba.fastjson.JSON;
import com.labtalk.admin.config.JwtTokenUtil;
import com.labtalk.admin.constant.HttpStatus;
import com.labtalk.admin.pojo.common.ResponseVo;
import com.labtalk.admin.pojo.entity.UserEntity;
import com.labtalk.admin.pojo.model.UserModel;
import com.labtalk.admin.service.LoginService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @Author G-pointy
 * @Date 2022-08-09
 * @Description: LoginServiceImpl
 */
@Service
public class LoginServiceImpl implements LoginService {
    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Value("${jwt.tokenPrefix}")
    private String tokenPrefix;

    @Value("${jwt.header}")
    private String tokenHeader;

    private static final String REDIS_USER = "user";

    @Override
    public ResponseVo login(UserModel userModel) {
        // 参数校验
        if (StringUtils.isEmpty(userModel.getUsername()) || StringUtils.isEmpty(userModel.getPassword())) {
            return ResponseVo.error(HttpStatus.PARAM_REQUIRED, "用户名或密码必填", null);
        }

        UserEntity userEntity = (UserEntity) userDetailsService.loadUserByUsername(userModel.getUsername());
        if (Objects.isNull(userEntity) || !passwordEncoder.matches(userModel.getPassword(), userEntity.getPassword())) {
            return  ResponseVo.error(HttpStatus.PARAM_ERROR, "用户名或密码错误", null);
        }

        // 将用户数据存到redis中，用于jwt登录拦截器对后续请求做处理
        ValueOperations<Object, Object> valueOperations = redisTemplate.opsForValue();
        String userStr = JSON.toJSON(userEntity).toString();
        valueOperations.set(REDIS_USER + userEntity.getId(), userStr);

        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userEntity, null, userEntity.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);

        // 获取token
        Map<String, String> tokenMap = new HashMap<>();
        String token = jwtTokenUtil.generateToken(userEntity.getId());
        tokenMap.put(tokenHeader, tokenPrefix + " " + token);
        return ResponseVo.success(HttpStatus.SUCCESS, "登录成功", tokenMap);
    }
}
